package orm;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public abstract class FitnessDataDBHelper {

	/**
	 * 
	 * @param context
	 * @param FitnessData
	 * @return the row ID of the newly inserted row, the the number of rows
	 *         affected if Fitnessdata is updated , or -1 if an error occurred
	 */
	public static long saveFitnessData(Context context, FitnessData fitnessData) {

		if (fitnessData.getID() != -1 && getFitnessDataByID(context, fitnessData.getID()) != null) {
			return updateFitnessData(context, fitnessData);
		} else {
			return addFitnessData(context, fitnessData);
		}
	}

	/**
	 * 
	 * @param context
	 * @param person
	 * @return the row ID of the newly inserted row, or -1 if an error occurred
	 */
	public static long addFitnessData(Context context, FitnessData fitnessData) {

		DBHelper mDbHelper = new DBHelper(context);
		SQLiteDatabase db = mDbHelper.getWritableDatabase();

		long id = db.insert(DBContract.FitnessData.TABLE_NAME,
				DBContract.FitnessData.COLUMN_NAME_NULLABLE,
				getAllValues(fitnessData));
		mDbHelper.close();
		return id;
	}

	/**
	 * 
	 * @param context
	 * @param fitnessData
	 * @return the number of rows affected
	 */
	public static long updateFitnessData(Context context,
			FitnessData fitnessData) {

		DBHelper mDbHelper = new DBHelper(context);
		SQLiteDatabase db = mDbHelper.getWritableDatabase();

		long id = db.update(DBContract.FitnessData.TABLE_NAME,
				getAllValues(fitnessData),
				DBContract.FitnessData.COLUMN_FITNESSDATA_ID + " = "
						+ fitnessData.getID(), null);
		mDbHelper.close();
		return id;
	}

	/**
	 * 
	 * @param context
	 * @param id
	 * @return null if no FitnessData with the given id is found
	 */
	public static FitnessData getFitnessDataByID(Context context, int id) {
		DBHelper mDbHelper = new DBHelper(context);
		SQLiteDatabase db = mDbHelper.getReadableDatabase();

		String selection = DBContract.FitnessData.COLUMN_FITNESSDATA_ID + " = "
				+ id;

		Cursor c = db.query(DBContract.FitnessData.TABLE_NAME, // The table to
																// query
				getAllProjectionCols(), // The columns to return
				selection, // The columns for the WHERE clause
				null, // The values for the WHERE clause
				null, // don't group the rows
				null, // don't filter by row groups
				null // The sort order
				);

		Date date = new Date();
		SimpleDateFormat iso8601Format = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		if (c.moveToFirst()) {

			try {
				date = iso8601Format.parse(c.getString(3));
			} catch (java.text.ParseException e) {
				date = new Date();
				e.printStackTrace();
			}
			mDbHelper.close();
			return new FitnessData(Integer.parseInt(c.getString(0)),
					Integer.parseInt(c.getString(1)), c.getString(2), date,
					Integer.parseInt(c.getString(4)), Integer.parseInt(c
							.getString(5)), Integer.parseInt(c.getString(6)),
					Integer.parseInt(c.getString(7)));
		}
		mDbHelper.close();
		if (c != null && !c.isClosed()) {
			c.close();
		}
		if (db != null) {
			db.close();
		}

		return null;
	}

	/**
	 * 
	 * @param context
	 * @param id
	 * @return null if no FitnessData with the given id is found
	 */
	public static ArrayList<FitnessData> getFitnessDataByPersonFK(
			Context context, int person_fk) {
		DBHelper mDbHelper = new DBHelper(context);
		SQLiteDatabase db = mDbHelper.getReadableDatabase();

		String selection = DBContract.FitnessData.COLUMN_PERSON_FK + " = "
				+ person_fk;

		Cursor c = db.query(DBContract.FitnessData.TABLE_NAME, // The table to
																// query
				getAllProjectionCols(), // The columns to return
				selection, // The columns for the WHERE clause
				null, // The values for the WHERE clause
				null, // don't group the rows
				null, // don't filter by row groups
				null // The sort order
				);

		Date date = new Date();
		ArrayList<FitnessData> fitnessDataList = new ArrayList<FitnessData>();
		SimpleDateFormat iso8601Format = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		if (c.moveToFirst()) {

			do {
				try {
					date = iso8601Format.parse(c.getString(3));
				} catch (java.text.ParseException e) {
					date = null;
					e.printStackTrace();
					mDbHelper.close();
				}

				fitnessDataList.add(new FitnessData(Integer.parseInt(c
						.getString(0)), Integer.parseInt(c.getString(1)), c
						.getString(2), date, Integer.parseInt(c.getString(4)),
						Integer.parseInt(c.getString(5)), Integer.parseInt(c
								.getString(6)),
						Integer.parseInt(c.getString(7))));

			} while (c.moveToNext());
		}

		if (c != null && !c.isClosed()) {
			c.close();
		}
		if (db != null) {
			db.close();
		}

		mDbHelper.close();
		return fitnessDataList;
	}

	/**
	 * ContentValues: This class is used to store a set of values that the
	 * ContentResolver can process.
	 * 
	 * @param FitnessData
	 * @return a map of all values/columns, where column names are the keys
	 */
	private static ContentValues getAllValues(FitnessData fitnessData) {

		ContentValues values = new ContentValues();
		values.put(DBContract.FitnessData.COLUMN_NOTES, fitnessData.getNotes());
		values.put(DBContract.FitnessData.COLUMN_PERSON_FK,
				fitnessData.getPersonFK());
		values.put(DBContract.FitnessData.COLUMN_DATE, fitnessData.getDate()
				.toString());
		values.put(DBContract.FitnessData.COLUMN_HEIGHT, fitnessData.getHight());
		values.put(DBContract.FitnessData.COLUMN_WEIGHT,
				fitnessData.getWeight());
		values.put(DBContract.FitnessData.COLUMN_FITNESS,
				fitnessData.getFitness());
		values.put(DBContract.FitnessData.COLUMN_MOTIVATION,
				fitnessData.getMotivation());

		return values;
	}

	/**
	 * Defines a projection that specifies which columns from the database you
	 * will actually use after this query.
	 * 
	 * @return
	 */
	private static String[] getAllProjectionCols() {

		String[] projection = { DBContract.FitnessData.COLUMN_FITNESSDATA_ID,
				DBContract.FitnessData.COLUMN_PERSON_FK,
				DBContract.FitnessData.COLUMN_NOTES,
				DBContract.FitnessData.COLUMN_DATE,
				DBContract.FitnessData.COLUMN_HEIGHT,
				DBContract.FitnessData.COLUMN_WEIGHT,
				DBContract.FitnessData.COLUMN_FITNESS,
				DBContract.FitnessData.COLUMN_MOTIVATION };

		return projection;
	}

	/**
	 * 
	 * @param context
	 * @return
	 */
	public static ArrayList<FitnessData> getAllFitnessData(Context context) {
		ArrayList<FitnessData> fitnessDataList = new ArrayList<FitnessData>();

		DBHelper mDbHelper = new DBHelper(context);
		SQLiteDatabase db = mDbHelper.getReadableDatabase();

		Cursor c = db.query(DBContract.FitnessData.TABLE_NAME, // The table to
																// query
				getAllProjectionCols(), // The columns to return
				null, // The columns for the WHERE clause
				null, // The values for the WHERE clause
				null, // don't group the rows
				null, // don't filter by row groups
				null // The sort order
				);

		Date date;
		SimpleDateFormat iso8601Format = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		if (c.moveToFirst()) {
			do {
				try {
					date = iso8601Format.parse(c.getString(3));
				} catch (java.text.ParseException e) {
					date = new Date();
					e.printStackTrace();
				}

				fitnessDataList.add(new FitnessData(Integer.parseInt(c
						.getString(0)), Integer.parseInt(c.getString(1)), c
						.getString(2), date, Integer.parseInt(c.getString(4)),
						Integer.parseInt(c.getString(5)), Integer.parseInt(c
								.getString(6)),
						Integer.parseInt(c.getString(7))));

			} while (c.moveToNext());
		}

		if (c != null && !c.isClosed()) {
			c.close();
		}
		if (db != null) {
			db.close();
		}

		return fitnessDataList;
	}

	/*
	 * Creates empty Fitnessdata with the given Person id
	 */
	public static long addDummyFitnessdata(Context context, int person_id) {

		return addFitnessData(context, new FitnessData(0, person_id, "notes",
				new Date(), 198, 75, 5, 10));

	}

}
